package com.rocksea.app.db;

import android.content.Context;
import android.os.Message;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.rocksea.app.Account;
import com.rocksea.app.MyApplication;
import com.rocksea.app.UploadingTask;
import com.rocksea.app.db.HighStrain.GyDbHelper;
import com.rocksea.app.db.HighStrain.HighStrain;
import com.rocksea.app.db.SonicWave.ScDbHelper;
import com.rocksea.app.db.SonicWave.SonicWave;
import com.rocksea.app.db.StaticLoad.StaticLoad;
import com.rocksea.app.db.StaticLoad.StaticLoadDb;
import com.rocksea.app.db.history.HistoryDbHelper;
import com.rocksea.app.db.history.HistoryTable;
import com.rocksea.app.db.image.ImageDbHelper;
import com.rocksea.app.db.image.ImageTable;
import com.rocksea.app.db.lowStrain.DyDbHelper;
import com.rocksea.app.db.lowStrain.LowStrainDb;
import com.rocksea.app.db.uploadflag.UploadFlagDb;
import com.rocksea.app.entry.EndTest;
import com.rocksea.app.entry.ImageInfo;
import com.rocksea.app.entry.InspectionForm;
import com.rocksea.app.entry.JYData;
import com.rocksea.app.entry.TestData;
import com.rocksea.app.event.DeleteEvent;
import com.rocksea.app.fragment.FileCenterFragment;
import com.rocksea.app.http.HttpUtil;
import com.rocksea.app.interfaces.MyExecuteCallBack;
import com.rocksea.app.utils.FileHelper;
import com.rocksea.app.utils.PerUtils;
import com.rocksea.app.weight.SonicWaveImage;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by 吴志华 on 2017/7/31.
 * 数据库中心，包含数据库初始
 */

public class DbCenter {

    public static final long DAY_OF_TIME = 86400000;

    public static DyDbHelper mDyDbHelper;
    public static GyDbHelper mGyDbHelper;
    public static ScDbHelper mScDbHelper;
    public static StaticLoadDb mStaticLoadDbHelper;
    public static HistoryDbHelper mHistoryDbHelper;
    public static ImageDbHelper mImageDbHelper;
    public static UploadFlagDb mUploadFlagDbHelper;

    public static final int STATICLOAD_END = -4;
    public static final int SNOICWAVE_END = -3;
    public static final int LOWSTARIN_END = -2;
    public static final int LOWSTARIN = 1;
    public static final int LOWSTARIN_DATA = 2;
    public static final int SONICWAVE = 3;
    public static final int SONICWAVE_FACE = 4;
    public static final int SONICWAVE_DATA = 5;
    public static final int STATICLOAD = 6;
    public static final int STATICLOAD_DATA = 7;
    public static final int STATICLOAD_LOG = 8;
    public static final int HIGHSTRAIN = 9;
    private static final String UPLOAD_BASEINFOID = "UPLOAD_BASEINFOID";
    private static final String UPLOAD_PLANNUM = "UPLOAD_PLANNUM";
    private static final String UPLOAD_PILENO = "UPLOAD_PILENO";
    private static ExecutorService mExecutorService = Executors.newFixedThreadPool(1);

    public static void init(Context context)
    {
        UploadingDbHelper.init(context);
        mHistoryDbHelper = HistoryDbHelper.getInstance(context);
        mDyDbHelper = DyDbHelper.getInstance(context);
        mGyDbHelper = GyDbHelper.getInstance(context);
        mScDbHelper = ScDbHelper.getInstance(context);
        mStaticLoadDbHelper = StaticLoadDb.getInstance(context);
        mImageDbHelper = ImageDbHelper.getInstance(context);
        mUploadFlagDbHelper = UploadFlagDb.newInstance(context);
        PileIdDbHelper.init(context);
    }
    public static void close()
    {
        if (mExecutorService!=null)
        {
            if (mExecutorService.isShutdown())
            {
                mExecutorService.shutdown();
                try
                {
                    mExecutorService.awaitTermination(2, TimeUnit.SECONDS);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
            mExecutorService = null;
        }
    }


    private static String sonicWaveUUID = null;

    public static void save(final String msg,final int code)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                boolean isAutoUpLoad = HttpUtil.isFileAutoUpload();
                FileCenterFragment.StateEvent stateEvent = new FileCenterFragment.StateEvent();
                switch (code)
                {
                    case LOWSTARIN:
                        LowStrainDb lowStrainDb = new LowStrainDb(msg);
                        PerUtils.setString(UPLOAD_BASEINFOID,lowStrainDb.uuid);
                        PerUtils.setString(UPLOAD_PILENO,lowStrainDb.pileNo);
                        PerUtils.setString(UPLOAD_PLANNUM,lowStrainDb.inspectionFormNum);
                        mHistoryDbHelper.save(new HistoryTable(lowStrainDb));
                        mDyDbHelper.save(lowStrainDb);
                        stateEvent.message = String.format("接收到%s桩低应变数据",lowStrainDb.pileNo);
                        break;

                    case LOWSTARIN_DATA:
                        LowStrainDb.LowStrainDataDb lowStrainData = new LowStrainDb.LowStrainDataDb(msg);
                        mDyDbHelper.save(lowStrainData);
                        stateEvent.message = String.format("接收到第%s锤数据",lowStrainData.curNumber);
                        break;

                    case DbCenter.LOWSTARIN_END:
                        stateEvent.message = "低应变实验结束";
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.TEST_DY,UpLoadingTable.DEFAULT_UUID);
                        break;

                    case HIGHSTRAIN:
                        HighStrain highStrain = new HighStrain(msg);
                        mHistoryDbHelper.save(new HistoryTable(highStrain));
                        PileId pileId = PileIdDbHelper.queryPlanIdAndPileId(highStrain.serialNo,highStrain.pileNo);

                        highStrain.inspectionFormId = pileId.planId;
                        highStrain.inspectionFormNum = pileId.planNum;
                        highStrain.pileId = pileId.pileId;

                        PerUtils.setString(UPLOAD_BASEINFOID,highStrain.uuid);
                        PerUtils.setString(UPLOAD_PILENO,highStrain.pileNo);
                        PerUtils.setString(UPLOAD_PLANNUM,highStrain.inspectionFormNum);
                        mGyDbHelper.save(highStrain);
                        stateEvent.message = String.format("接收到%s桩高应变数据",highStrain.pileNo);
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.TEST_GY,UpLoadingTable.DEFAULT_UUID);
                        break;

                    case SONICWAVE:
                        SonicWave sonicWave =new SonicWave(msg);
                        sonicWaveUUID = sonicWave.uuid;
                        PerUtils.setString(UPLOAD_PILENO,sonicWave.pileNo);
                        PerUtils.setString(UPLOAD_PLANNUM,sonicWave.inspectionFormNum);
                        PerUtils.setString(UPLOAD_BASEINFOID,sonicWave.uuid);
                        mHistoryDbHelper.save(new HistoryTable(sonicWave));
                        mScDbHelper.save(sonicWave);
                        stateEvent.message = String.format("接收到%s桩声波数据",sonicWave.pileNo);
                        break;

                    case SONICWAVE_DATA:
                        if (sonicWaveUUID == null)
                            sonicWaveUUID =  PerUtils.getString(UPLOAD_BASEINFOID,"");
                        SonicWave.SonicWaveData sonicWaveData = new SonicWave.SonicWaveData(msg);
                        mScDbHelper.insertWaveData(sonicWaveData.getSonicWaveDatas(),sonicWaveUUID);
                        if (sonicWaveData.getSonicWaveDatas() != null || sonicWaveData.getSonicWaveDatas().get(0) !=null)
                        {
                            if (sonicWaveData.getSonicWaveDatas().size() > 0)
                            {
                                stateEvent.message = String.format("接收到 %.1fm 测点数据",sonicWaveData.getSonicWaveDatas().get(0).depth/1000f);
                            }
                        }
                        break;

                    case SONICWAVE_FACE:
                        SonicWave.SonicWaveFace sonicWaveFace = new SonicWave.SonicWaveFace(msg);
                        mScDbHelper.insertWaveFace(sonicWaveFace.getSonicWaveFaces(),true);
                        stateEvent.message = "接收到剖面数据";
                        break;

                    case DbCenter.SNOICWAVE_END:
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.TEST_SC,UpLoadingTable.DEFAULT_UUID);
                        stateEvent.message = "声波实验结束";
                        break;

                    case STATICLOAD:
                        StaticLoad staticLoad = new StaticLoad(msg);
                        mHistoryDbHelper.save(new HistoryTable(staticLoad));
                        PerUtils.setString(UPLOAD_BASEINFOID,staticLoad.baseInfoId);
                        PerUtils.setString(UPLOAD_PILENO,staticLoad.pileNo);
                        PerUtils.setString(UPLOAD_PLANNUM,staticLoad.inspectionFormNum);
                        mStaticLoadDbHelper.insert(staticLoad);
                        stateEvent.message = String.format("接收到%s桩静载数据",staticLoad.pileNo);
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.TEST_JZ,UpLoadingTable.DEFAULT_UUID);
                        break;

                    case STATICLOAD_DATA:
                        StaticLoad.StaticLoadTest staticLoadTest = new StaticLoad.StaticLoadTest(msg);
                        mStaticLoadDbHelper.insert(staticLoadTest);
                        stateEvent.message = String.format("接收到第%s级第%s采样数据",staticLoadTest.grade,staticLoadTest.sampleCount);
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.JY_SAMPLE_DATA,staticLoadTest.uuid);
                            break;

                    case STATICLOAD_LOG:
                        StaticLoad.StaticLoadLog staticLoadLog = new StaticLoad.StaticLoadLog(msg);
                        stateEvent.message = String.format("接收到测试日志(%s)",staticLoadLog.eventInfo);
                        mStaticLoadDbHelper.insert(staticLoadLog);
                        if (isAutoUpLoad)
                            insertUploadingTable(HistoryTable.JY_LOG_DATA,staticLoadLog.uuid);
                            break;

                    case DbCenter.STATICLOAD_END:
                        //实时结束试桩
                        EndTest staticLoadEnd = JSON.parseObject(msg, EndTest.class);
                        stateEvent.message = "静载实验结束";
                        DbCenter.mStaticLoadDbHelper.makeTestIsOver(staticLoadEnd.baseInfoId);
                        //添加一个日志
                        if (DbCenter.mStaticLoadDbHelper.queryLogCounts(staticLoadEnd.baseInfoId) == 0)
                        {
                            StaticLoad.StaticLoadLog makeLog = new StaticLoad.StaticLoadLog(JYData.makeLogJson(staticLoadEnd.baseInfoId));
                            DbCenter.mStaticLoadDbHelper.insert(makeLog);
                            if (isAutoUpLoad)
                            {
                                insertUploadingTable(HistoryTable.JY_LOG_DATA,makeLog.uuid);
                            }
                        }

                        if (isAutoUpLoad)
                        {
                            insertUploadingTable(HistoryTable.TEST_JZ,UpLoadingTable.DEFAULT_UUID);
                        }
                        break;
                }

                EventBus.getDefault().post(stateEvent);
            }
        });
    }

    private static void insertUploadingTable(int mode,String uuid)
    {
        String baseInfoId = PerUtils.getString(UPLOAD_BASEINFOID,null);
        String planNum = PerUtils.getString(UPLOAD_PLANNUM,null);
        String pileNo = PerUtils.getString(UPLOAD_PILENO,null);
        if (uuid == null || planNum == null || pileNo == null)
            return;
        switch (mode)
        {
            case HistoryTable.TEST_DY:
            case HistoryTable.TEST_GY:
            case HistoryTable.TEST_SC:
            case HistoryTable.TEST_JZ:
                UploadingDbHelper.insert(new UpLoadingTable(mode,baseInfoId,pileNo,planNum,UpLoadingTable.DEFAULT_UUID));
                break;

            case HistoryTable.JY_SAMPLE_DATA:
            case HistoryTable.JY_LOG_DATA:
                UploadingDbHelper.insert(new UpLoadingTable(mode,baseInfoId,pileNo,planNum,uuid));
                break;
        }
    }


    public static void makeAsUpLoaded(final String baseInfoId,final int dataType)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mHistoryDbHelper.makeAsUpLoad(baseInfoId);
                switch (dataType)
                {
                    case HistoryTable.TEST_DY:
                        mDyDbHelper.makeAsUpLoad(baseInfoId);
                        break;
                    case HistoryTable.TEST_JZ:
                        mStaticLoadDbHelper.makeAdUpLoad(baseInfoId);
                        break;
                    case HistoryTable.TEST_SC:
                        mScDbHelper.makeAdUpLoad(baseInfoId);
                        break;
                    case HistoryTable.TEST_GY:
                        mGyDbHelper.makeAsUpLoad(baseInfoId);
                        break;
                }
            }
        });
    }



    public static final int SC_BASE_DATE = 2;
    public static final int SC_NODE_DATE = 3;
    public static final int SC_SECTION_DATE = 4;

    public static final int JY_BASE_DATE = 5;
    public static final int JY_SAMPLE_DATE = 6;
    public static final int JY_LOG_DATE = 7;


    public static void makeUpLoaded(final String baseInfoId, final int type)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                switch (type)
                {
                    case SC_BASE_DATE:
                        mScDbHelper.makeBaseInfoAsUpLoad(baseInfoId);
                        break;
                    case SC_NODE_DATE:
                        mScDbHelper.makeNodeAsUpLoad(baseInfoId);
                        break;
                    case SC_SECTION_DATE:
                        mScDbHelper.makeSectionAsUpLoad(baseInfoId);
                        break;
                    case JY_BASE_DATE:
                        mStaticLoadDbHelper.makeBaseInfoAsUpLoad(baseInfoId);
                        break;
                    case JY_LOG_DATE:
                        mStaticLoadDbHelper.makeLogAsUpLoad(baseInfoId);
                        break;
                    case JY_SAMPLE_DATE:
                        mStaticLoadDbHelper.makeSampleAsUpLoad(baseInfoId);
                        break;
                }
            }
        });
    }


    public static void delete(final HistoryTable mHistoryTable)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                int historyCode =mHistoryDbHelper.delete(mHistoryTable.BaseInfoId);
                Log.d("delete: ",historyCode+"");
                switch (mHistoryTable.TestMode)
                {
                    case TestData.DY:
                        mDyDbHelper.delete(mHistoryTable.BaseInfoId);
                        break;
                    case TestData.GY:
                        mGyDbHelper.delete(mHistoryTable.BaseInfoId);
                        break;
                    case TestData.SC:
                        mScDbHelper.delete(mHistoryTable.BaseInfoId);
                        break;
                    default:
                        break;
                }
            }
        });
    }
    public static void delete(final ArrayList<HistoryTable> historyTables)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < historyTables.size(); i++)
                {
                    HistoryTable mHistoryTable = historyTables.get(i);
                    int historyCode =mHistoryDbHelper.delete(mHistoryTable.BaseInfoId);
                    Log.d("delete: ",historyCode+"");
                    switch (mHistoryTable.Type)
                    {
                        case TestData.DY:
                            mDyDbHelper.delete(mHistoryTable.BaseInfoId);
                            break;
                        case TestData.GY:
                            mGyDbHelper.delete(mHistoryTable.BaseInfoId);
                            break;
                        case TestData.SC:
                            mScDbHelper.delete(mHistoryTable.BaseInfoId);
                            break;
                        case TestData.JZ:
                            mStaticLoadDbHelper.delete(mHistoryTable.BaseInfoId);
                            break;
                        default:
                            break;
                    }
                }
                DeleteEvent deleteEvent = new DeleteEvent();
                deleteEvent.setHistoryTables(historyTables);
                deleteEvent.setEventType(DeleteEvent.OVER_DELETE);
                EventBus.getDefault().post(deleteEvent);
            }
        });
    }

    public static void  deleteImage(final long pileId, final String fileName)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mImageDbHelper.delete(pileId,fileName);
            }
        });
    }

    public static void makeImageAsUpLoad(final long pileId, final String fileName)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mImageDbHelper.makeAsUpLoad(pileId,fileName);
            }
        });

    }

    public static void makeAsIsValid(final String uuid,final int i)
    {
        mExecutorService.execute(new Runnable() {
            @Override
            public void run() {
                mDyDbHelper.makeAsIsValid(uuid,i);
            }
        });
    }

    public static void querySonicWaveSection(final String baseInfoId, final MyExecuteCallBack<List<SonicWave.SonicWaveFace>> callBack)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mScDbHelper.querySectionByBaseInfoId(baseInfoId,callBack);
            }
        });

    }

    public static void makeScWaveAsIsValid(final String uuid, final int i)
    {
        mExecutorService.execute(new Runnable() {
            @Override
            public void run() {
                mScDbHelper.makeAsIsValid(uuid,i);
            }
        });
    }

    public static void insertSonicWaveServiceId(final String uuid,final int returnCode)
    {
        mExecutorService.execute(new Runnable() {
            @Override
            public void run()
            {
                mScDbHelper.insertSonicWaveServiceId(uuid,returnCode);
            }
        });
    }

    public static void makeAsSonicWaveFaceUpLoad(final String uuid)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mScDbHelper.makeAsSonicWaveFaceUpLoad(uuid);
            }
        });
    }


    public static void makeFlagTableUploaded(final String uuid)
    {
        mExecutorService.execute(new Runnable() {
            @Override
            public void run() {
                mUploadFlagDbHelper.makeUpLoad(uuid);

            }
        });
    }



    public static void insertServiceId(final String baseInfoId, final int returnCode)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mStaticLoadDbHelper.insertServiceId(baseInfoId,returnCode);
            }
        });
    }

    public static void insertLowStrainServiceId(final String baseInfoId, final int returnCode)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mDyDbHelper.insertServiceId(baseInfoId,returnCode);
            }
        });
    }
    public static void makeAsLowStrainDataUpLoad(final String uuid) {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                mDyDbHelper.makeWaveDataAsUpLoaded(uuid);
            }
        });
    }

    public static void savePileId(final List<InspectionForm.InspectionFormListBean> inspectionFormList)
    {
        mExecutorService.execute(new Runnable()
        {
            @Override
            public void run()
            {
                ArrayList<PileId> insertPiles = new ArrayList<>();
                for (int i = 0; i < inspectionFormList.size(); i++)
                {
                    String planNum = inspectionFormList.get(i).number;
                    long planId = inspectionFormList.get(i).id;
                    for (int i1 = 0; i1 < inspectionFormList.get(i).pileList.size(); i1++)
                    {
                        if (PileIdDbHelper.queryCount(planNum,inspectionFormList.get(i).pileList.get(i1).pileNo) == 0)
                        {
                            insertPiles.add(new PileId(
                                    planNum,
                                    inspectionFormList.get(i).pileList.get(i1).pileNo,
                                    planId,
                                    Long.parseLong(inspectionFormList.get(i).pileList.get(i1).pileId)
                            ));
                        }
                    }
                }
                if (insertPiles.size() > 0)
                    PileIdDbHelper.insert(insertPiles);
            }
        });

    }

}
